Minimum insertion steps to make a string palindrome [Longest Common Subsequence]¶
Time: O(N^2); Space: O(N); hard
Given a string s. In one step you can insert any character at any index of the string.
Return the minimum number of steps to make s palindrome.
A Palindrome String is one that reads the same backward as well as forward.
Example 1:
Input: s = “zzazz”
Output: 0
Explanation:
The string “zzazz” is already palindrome we don’t need any insertions.
Example 2:
Input: s = “mbadm”
Output: 2
Explanation:
String can be “mbdadbm” or “mdbabdm”.
Example 3:
Input: s = “leetcode”
Output: 5
Explanation:
Inserting 5 characters the string becomes “leetcodocteel”.
Example 4:
Input: s = “g”
Output: 0
Example 5:
Input: s = “no”
Output: 1
Constraints:
1 <= len(s) <= 500
All characters of s are lower case English letters.
Hints:
Is dynamic programming suitable for this problem ?
If we know the longest palindromic sub-sequence is x and the length of the string is n then, what is the answer to this problem? It is n - x as we need n - x insertions to make the remaining characters also palindrome.
[2]:
### 1. Dynamic programming [O(N^2), O(N)]
[3]:
class Solution1(object):
"""
Time: O(N^2)
Space: O(N)
"""
def minInsertions(self, s):
"""
:type s: str
:rtype: int
"""
def longestCommonSubsequence(text1, text2):
if len(text1) < len(text2):
return self.longestCommonSubsequence(text2, text1)
dp = [[0 for _ in range(len(text2)+1)] for _ in range(2)]
for i in range(1, len(text1)+1):
for j in range(1, len(text2)+1):
dp[i%2][j] = dp[(i-1)%2][j-1]+1 if text1[i-1] == text2[j-1] \
else max(dp[(i-1)%2][j], dp[i%2][j-1])
return dp[len(text1)%2][len(text2)]
return len(s)-longestCommonSubsequence(s, s[::-1])
[5]:
sol = Solution1()
s = "zzazz"
assert sol.minInsertions(s) == 0
s = "mbadm"
assert sol.minInsertions(s) == 2
s = "leetcode"
assert sol.minInsertions(s) == 5
s = "g"
assert sol.minInsertions(s) == 0
s = "no"
assert sol.minInsertions(s) == 1